/*
*
* Copyright (C) 2004 - 2008 BitLaboratory (see http://www.bitlaboratory.com)
* All rights reserved. 
*
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
*    derived from this software without specific prior written permission. 
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
* OF SUCH DAMAGE.
*
* You can find the latest version of this library at http://www.bitlaboratory.com
*
*/


using System;
using System.Drawing;
using Microsoft.Win32;
using BitLaboratory.Win32Api.Drawing;

namespace BitLaboratory.Win32Api.Themes
{
	/// <summary>
	/// 
	/// </summary>
	public class ThemedColorSheme
	{
		private static bool initializedClass;

		private static Color highlightColor;
		private static Color highlightDarkColor;
		private static Color highlightLightColor;
		private static Color menuBorderColor;
		private static Color menuColor;
		private static Color selectedColor;

		static ThemedColorSheme()
		{
			ThemedColorSheme.initializedClass = true;
			ThemedColorSheme.CalculateColors();
			SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(ThemedColorSheme.OnUserPreferenceChanged);
		}

		public ThemedColorSheme()
		{

		}

		public static bool Initialized
		{
			get{ return initializedClass; }
		}

		private static void CalculateColors()
		{
			if (ThemedColorSheme.CurrentDisplayColorDepth() >= 0x10)
			{
				int red = (int) (((SystemColors.Highlight.R - SystemColors.Window.R) * 0.3) + SystemColors.Window.R);
				int green = (int) (((SystemColors.Highlight.G - SystemColors.Window.G) * 0.3) + SystemColors.Window.G);
				int blue = (int) (((SystemColors.Highlight.B - SystemColors.Window.B) * 0.3) + SystemColors.Window.B);
				ThemedColorSheme.highlightColor = Color.FromArgb(red, green, blue);
				
				red = (int) (((SystemColors.Highlight.R - SystemColors.Window.R) * 0.45) + SystemColors.Window.R);
				green = (int) (((SystemColors.Highlight.G - SystemColors.Window.G) * 0.45) + SystemColors.Window.G);
				blue = (int) (((SystemColors.Highlight.B - SystemColors.Window.B) * 0.45) + SystemColors.Window.B);
				ThemedColorSheme.highlightDarkColor = Color.FromArgb(red, green, blue);
				
				red = (int) (((SystemColors.Highlight.R - SystemColors.Window.R) * 0.1) + SystemColors.Window.R);
				green = (int) (((SystemColors.Highlight.G - SystemColors.Window.G) * 0.1) + SystemColors.Window.G);
				blue = (int) (((SystemColors.Highlight.B - SystemColors.Window.B) * 0.1) + SystemColors.Window.B);
				ThemedColorSheme.highlightLightColor = Color.FromArgb(red, green, blue);
				
				red = (int) (((ThemedColorSheme.highlightColor.R - SystemColors.Control.R) * 0.25) + SystemColors.Control.R);
				green = (int) (((ThemedColorSheme.highlightColor.G - SystemColors.Control.G) * 0.25) + SystemColors.Control.G);
				blue = (int) (((ThemedColorSheme.highlightColor.B - SystemColors.Control.B) * 0.25) + SystemColors.Control.B);
				ThemedColorSheme.selectedColor = Color.FromArgb(red, green, blue);
				
				red = (int) (SystemColors.ControlDark.R * 0.8);
				green = (int) (SystemColors.ControlDark.G * 0.8);
				blue = (int) (SystemColors.ControlDark.B * 0.8);
				ThemedColorSheme.menuBorderColor = Color.FromArgb(red, green, blue);
				
				if (ThemedColorSheme.CurrentDisplayColorDepth() <= 0x10)
				{
					ThemedColorSheme.menuColor = SystemColors.ControlLightLight;
				}
				else
				{
					red = (int) (((SystemColors.Control.R - Color.White.R) * 0.2) + Color.White.R);
					green = (int) (((SystemColors.Control.G - Color.White.G) * 0.2) + Color.White.G);
					blue = (int) (((SystemColors.Control.B - Color.White.B) * 0.2) + Color.White.B);
					ThemedColorSheme.menuColor = Color.FromArgb(red, green, blue);
				}
			}
			else
			{
				ThemedColorSheme.highlightLightColor = ThemedColorSheme.highlightColor;
				ThemedColorSheme.highlightColor = SystemColors.ControlLightLight;
				ThemedColorSheme.highlightDarkColor = ThemedColorSheme.highlightColor;
				ThemedColorSheme.selectedColor = SystemColors.ControlLight;
				ThemedColorSheme.menuBorderColor = SystemColors.ControlDark;
				ThemedColorSheme.menuColor = SystemColors.ControlLightLight;
			}
		}

		public static int CurrentDisplayColorDepth()
		{
			IntPtr hDC = APIDeviceContext.GetDC(IntPtr.Zero);
			int planes = APIDeviceContext.GetDeviceCaps(hDC, DeviceContextIndexFlags.PLANES); // 14);
			int bitsPixel = APIDeviceContext.GetDeviceCaps(hDC, DeviceContextIndexFlags.BITSPIXEL); // 12);
			APIDeviceContext.ReleaseDC(IntPtr.Zero, hDC);
			return (planes * bitsPixel);
		}

		public static Color HighlightColor
		{
			get{ return ThemedColorSheme.highlightColor; }
		}

		public static Color HighlightDarkColor
		{
			get{ return ThemedColorSheme.highlightDarkColor; }
		}

		public static Color HighlightLightColor
		{
			get{ return ThemedColorSheme.highlightLightColor; }
		}

		public static Color MenuBorderColor
		{
			get{ return ThemedColorSheme.menuBorderColor; }
		}

		public static Color MenuColor
		{
			get{ return ThemedColorSheme.menuColor; }
		}

		public static Color SelectedColor
		{
			get{ return ThemedColorSheme.selectedColor; }
		}

		private static void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
		{
			ThemedColorSheme.CalculateColors();
		}
	}
}
